/*
 * Copyright (c) 2020 - present, Inspur Genersoft Co., Ltd.
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *       http://www.apache.org/licenses/LICENSE-2.0
 *
 *  Unless required by applicable law or agreed to in writing, software
 *  distributed under the License is distributed on an "AS IS" BASIS,
 *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 *  See the License for the specific language governing permissions and
 *  limitations under the License.
 */
package com.inspur.edp.lcm.metadata.rtservice;

import com.inspur.edp.i18n.resource.api.II18nResourceRTManager;
import com.inspur.edp.lcm.metadata.api.entity.GspMetadata;
import com.inspur.edp.lcm.metadata.api.entity.I18nResource;
import com.inspur.edp.lcm.metadata.api.entity.Metadata4Ref;
import com.inspur.edp.lcm.metadata.api.entity.MetadataCustomizationFilter;
import com.inspur.edp.lcm.metadata.api.entity.MetadataDto;
import com.inspur.edp.lcm.metadata.api.entity.MetadataRTFilter;
import com.inspur.edp.lcm.metadata.api.entity.ServiceUnitInfo;
import com.inspur.edp.lcm.metadata.api.service.MetadataRTService;
import com.inspur.edp.lcm.metadata.cache.MetadataDistCacheManager;
import com.inspur.edp.lcm.metadata.cache.RtCacheHandler;
import com.inspur.edp.lcm.metadata.common.MetadataDtoConverter;
import com.inspur.edp.lcm.metadata.common.MetadataSerializer;
import com.inspur.edp.lcm.metadata.common.configuration.I18nManagerHelper;
import com.inspur.edp.lcm.metadata.common.context.RuntimeContext;
import com.inspur.edp.lcm.metadata.spi.MetadataI18nService;
import io.iec.edp.caf.commons.layeringcache.cache.Cache;
import io.iec.edp.caf.commons.utils.SpringBeanUtils;
import io.iec.edp.caf.rpc.api.service.RpcClient;
import java.util.LinkedHashMap;
import java.util.List;

public class MetadataRTServiceImp implements MetadataRTService {
    MetadataRtUtils utils = new MetadataRtUtils();

    private Cache cacheManager;

    @Override
    public GspMetadata getMetadataRTByID(String id) {
        RpcClient client = SpringBeanUtils.getBean(RpcClient.class);
        LinkedHashMap<String, Object> params = new LinkedHashMap<>();
        params.put("id", id);
        MetadataDto response = client.invoke(MetadataDto.class, "com.inspur.edp.lcm.metadata.serverapi.MetadataRTServerService.getMetadataDtoRTByID", "Lcm", params, null);
        return MetadataDtoConverter.asMetadata(response);
    }

    @Override
    public GspMetadata getMetadata(String id) {
        String language = RuntimeContext.getLanguage();
        String metadataKey = RtCacheHandler.getMetadataCacheKey(id, language);
        Cache cacheManager = MetadataDistCacheManager.getMetadataCache();
        GspMetadata metadata = cacheManager.get(metadataKey, GspMetadata.class);
        if (metadata != null) {
            return metadata;
        }
        RpcClient client = SpringBeanUtils.getBean(RpcClient.class);
        LinkedHashMap<String, Object> params = new LinkedHashMap<>();
        params.put("id", id);
        MetadataDto response = client.invoke(MetadataDto.class, "com.inspur.edp.lcm.metadata.serverapi.MetadataRTServerService.getMetadataDto", "Lcm", params, null);
        metadata = MetadataDtoConverter.asMetadata(response);
        if (metadata != null) {
            cacheManager.put(metadataKey, metadata);
        }
        return metadata;
    }

    @Override
    public GspMetadata getMetadata(MetadataCustomizationFilter metadataCustomizationFilter) {
        String language = metadataCustomizationFilter.isI18n() ? RuntimeContext.getLanguage() : "";
        String metadataKey = RtCacheHandler.getMetadataCacheKey(metadataCustomizationFilter.getMetadataId(), language);
        cacheManager = MetadataDistCacheManager.getMetadataCache();
        GspMetadata metadata = cacheManager.get(metadataKey, GspMetadata.class);
        if (metadata != null) {
            return metadata;
        }

        RpcClient client = SpringBeanUtils.getBean(RpcClient.class);
        LinkedHashMap<String, Object> params = new LinkedHashMap<>();
        params.put("metadataCustomizationFilter", metadataCustomizationFilter);
        String response = client.invoke(String.class, "com.inspur.edp.lcm.metadata.serverapi.MetadataRTServerService.getMetadataString", "Lcm", params, null);
        metadata = new MetadataSerializer().deserialize(response, GspMetadata.class);

        if (metadataCustomizationFilter.isI18n()) {
            try {
                List<I18nResource> resources = SpringBeanUtils.getBean(II18nResourceRTManager.class).getI18nResource(metadata, language);
                MetadataI18nService service = I18nManagerHelper.getInstance().getI18nManager(metadata.getHeader().getType());
                if (service != null && resources != null && resources.size() > 0) {
                    GspMetadata result = service.merge(metadata, resources);
                    RtCacheHandler.updateMetadataCache(metadataKey, result);
                    return result;
                }
            } catch (Exception e) {
                //TODO 表单强制获取资源项，获取不到时会报错，异常太多，暂时catch住
            }
        }

        if (metadata != null) {
            cacheManager.put(metadataKey, metadata);
        }
        return metadata;
    }

    @Override
    public void loadAllMetadata() {
        RpcClient client = SpringBeanUtils.getBean(RpcClient.class);
        LinkedHashMap<String, Object> params = new LinkedHashMap<>();
        client.invoke(String.class, "com.inspur.edp.lcm.metadata.serverapi.MetadataRTServerService.loadAllMetadata", "Lcm", params, null);
    }

    @Override
    public List<Metadata4Ref> getMetadataRefList(String metadataTypes) {
        RpcClient client = SpringBeanUtils.getBean(RpcClient.class);
        LinkedHashMap<String, Object> params = new LinkedHashMap<>();
        params.put("metadataTypes", metadataTypes);
        String response = client.invoke(String.class, "com.inspur.edp.lcm.metadata.serverapi.MetadataRTServerService.getMetadataRefDtoListWithTypes", "Lcm", params, null);
        return utils.buildMetadata4RefList(response);
    }

    @Override
    public List<Metadata4Ref> getMetadataRefList() {
        RpcClient client = SpringBeanUtils.getBean(RpcClient.class);
        LinkedHashMap<String, Object> params = new LinkedHashMap<>();
        String response = client.invoke(String.class, "com.inspur.edp.lcm.metadata.serverapi.MetadataRTServerService.getMetadataRefDtoList", "Lcm", params, null);
        return utils.buildMetadata4RefList(response);
    }

    @Override
    public List<Metadata4Ref> getMetadataListByFilter(MetadataRTFilter filter) {
        RpcClient client = SpringBeanUtils.getBean(RpcClient.class);
        LinkedHashMap<String, Object> params = new LinkedHashMap<>();
        params.put("filter", utils.serializerMetadataRtFilter(filter));
        String response = client.invoke(String.class, "com.inspur.edp.lcm.metadata.serverapi.MetadataRTServerService.getMetadataDtoListByFilter", "Lcm", params, null);
        return utils.buildMetadata4RefList(response);
    }

    @Override
    public GspMetadata getMetadataBySemanticID(String metadataNamespace, String metadataCode, String metadataTypeCode) {
        RpcClient client = SpringBeanUtils.getBean(RpcClient.class);
        LinkedHashMap<String, Object> params = new LinkedHashMap<>();
        params.put("metadataNamespace", metadataNamespace);
        params.put("metadataCode", metadataCode);
        params.put("metadataTypeCode", metadataTypeCode);
        MetadataDto response = client.invoke(MetadataDto.class, "com.inspur.edp.lcm.metadata.serverapi.MetadataRTServerService.getMetadataDtoBySemanticID", "Lcm", params, null);
        return MetadataDtoConverter.asMetadata(response);
    }

    @Override
    public ServiceUnitInfo getServiceUnitInfo(String metadataId) {
        RpcClient client = SpringBeanUtils.getBean(RpcClient.class);
        LinkedHashMap<String, Object> params = new LinkedHashMap<>();
        params.put("metadataId", metadataId);
        return client.invoke(ServiceUnitInfo.class, "com.inspur.edp.lcm.metadata.serverapi.MetadataRTServerService.getServiceUnitInfo", "Lcm", params, null);
    }
}
